package com.blqy.fr.template.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.blqy.fr.common.execption.BlQyException;
import com.blqy.fr.common.util.AuthContextHolder;
import com.blqy.fr.model.template.Template;
import com.blqy.fr.model.template.TemplateTag;
import com.blqy.fr.model.template.TemplateTagRelation;
import com.blqy.fr.template.mapper.TemplateInfoMapper;
import com.blqy.fr.template.mapper.TemplateTagMapper;
import com.blqy.fr.template.mapper.TemplateTagRelationMapper;
import com.blqy.fr.template.service.TemplateInfoService;
import com.blqy.fr.vo.template.ChildTagItemVo;
import com.blqy.fr.vo.template.ParentTagGroupVo;
import com.blqy.fr.vo.template.TemplateResponseVo;
import com.blqy.fr.vo.template.TemplateVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;


import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class TemplateInfoServiceImpl extends ServiceImpl<TemplateInfoMapper, Template> implements TemplateInfoService {

    @Autowired
    private TemplateInfoMapper templateInfoMapper;
    @Autowired
    private TemplateTagMapper templateTagMapper;
    @Autowired
    private TemplateTagRelationMapper relationMapper;

    @Override
    public List<TemplateVo> getTemplateInfo(String templateName) {
        return templateInfoMapper.getTemplateInfo(templateName);
    }

    @Override
    public void updateTemplateStructure(TemplateResponseVo request) {

        Long templateId = request.getTemplateId();

        // 1. 校验模板是否存在
        Template template = templateInfoMapper.selectById(templateId);
        if (template == null) {
            throw new BlQyException(501,"模板不存在");
        }

        // 2. 更新模板基本信息
        if (request.getTemplateName() != null && !request.getTemplateName().equals(template.getTemplateName())) {
            // 检查模板名是否重复
            if (templateInfoMapper.existsByName(request.getTemplateName())) {
                throw new BlQyException(502,"模板名字重复");
            }
            template.setTemplateName(request.getTemplateName());
            templateInfoMapper.updateById(template);
        }

        // 3. 获取当前模板所有有效的标签ID（用于对比删除）
        List<Long> currentTagIds = relationMapper.selectActiveTagIdsByTemplateId(templateId);
        Set<Long> toKeepTagIds = new HashSet<>();

        // 4. 处理所有分组（包括顶级）
        for (ParentTagGroupVo group : request.getGroups()) {
            Long parentId = null;

            // 4.1 处理父标签（如果存在）
            if (group.getParentTagName() != null) {
                parentId = processParentTag(templateId, group);
            }

            // 4.2 处理子标签
            if (group.getChildren() != null) {
                for (ChildTagItemVo child : group.getChildren()) {
                    Long childTagId = processChildTag(templateId, child, parentId);
                    toKeepTagIds.add(childTagId);
                }
            }
        }

        // 5. 软删除不再使用的标签关联
        for (Long currentId : currentTagIds) {
            if (!toKeepTagIds.contains(currentId)) {
                relationMapper.softDeleteByTemplateAndTag(templateId, currentId);
                // 可选：级联软删除 template_tag（如果该标签不再被任何模板使用）
                // cascadeSoftDeleteTagIfUnused(currentId);
            }
        }
    }

    @Override
    public Long getTemplateIdByTeamId(Long teamId) {
        Long userId = AuthContextHolder.getUserId();
        Template template = templateInfoMapper.selectOne(new LambdaQueryWrapper<Template>().eq(Template::getTeamId, teamId)
                .eq(Template::getUserId, userId)
                .orderByDesc(Template::getUpdateTime)
                .last("limit 1")
                );
        if (template.getId() != null) {
            return template.getId();
        }else {
            Assert.isTrue(false,"没有找到对应的模板");
        }
        return template.getId();
    }

    @Override
    public TemplateResponseVo getTemplateStructure(String templateName, Long teamId) {
        return null;
    }

    @Override
    public String getTemplateNameByTeamId(Long teamId) {

        Long userId = AuthContextHolder.getUserId();
        Template template = templateInfoMapper.selectOne(new LambdaQueryWrapper<Template>().eq(Template::getTeamId, teamId)
                .eq(Template::getUserId, userId)
                .orderByDesc(Template::getUpdateTime)
                .last("limit 1")
        );
        if (template.getId() != null) {
            return template.getTemplateName();
        }else {
            Assert.isTrue(false,"没有找到对应的模板");
        }
        return template.getTemplateName();
    }

    /**
     * 处理父标签：存在则复用，不存在则创建
     */
    private Long processParentTag(Long templateId, ParentTagGroupVo group) {
        // 先尝试根据 parentId 查
        if (group.getParentId() != null) {
            TemplateTag existing = templateTagMapper.selectById(group.getParentId());
            if (existing != null) {
                return existing.getId();
            }
        }

        // 否则根据名称查找（同一模板下父标签名应唯一）
        TemplateTag existingByName = templateTagMapper.selectByTemplateNameAndTag(templateId, group.getParentTagName());
        if (existingByName != null) {
            return existingByName.getId();
        }
        return null;
    }

    /**
     * 处理子标签：新增或更新
     */
    private Long processChildTag(Long templateId, ChildTagItemVo child, Long parentId) {
        if (child.getChildTagId() != null) {
            // 更新现有标签
            TemplateTag tag = new TemplateTag();
            tag.setId(child.getChildTagId());
            tag.setTemplateTag(child.getTagName());
            tag.setTagType(child.getTagType());
            tag.setParentId(parentId);
            templateTagMapper.updateById(tag);

            // 更新关联关系
            TemplateTagRelation relation = new TemplateTagRelation();
            relation.setTemplateId(templateId);
            relation.setTemplateTagId(child.getChildTagId());
            relation.setIsVisible(child.getIsVisible());
            relation.setIsRequired(child.getIsRequired());
            relation.setIsEdit(child.getIsEdit());
            relationMapper.updateByTemplateAndTag(relation);

            templateInfoMapper.updateTemplateTime(child.getTemplateId());

            return child.getChildTagId();
        } else {
            // 新增标签
            TemplateTag newTag = new TemplateTag();
            newTag.setTemplateTag(child.getTagName());
            newTag.setTagType(child.getTagType());
            newTag.setParentId(parentId);
            templateTagMapper.insert(newTag);

            TemplateTagRelation relation = new TemplateTagRelation();
            relation.setTemplateId(templateId);
            relation.setTemplateTagId(newTag.getId());
            relation.setIsVisible(child.getIsVisible());
            relation.setIsRequired(child.getIsRequired());
            relation.setIsEdit(child.getIsEdit());
            relationMapper.insert(relation);

            templateInfoMapper.updateTemplateTime(child.getTemplateId());

            return newTag.getId();
        }
    }

    @Override
    public TemplateResponseVo getTemplateStructure(String templateName) {
        // 1. 查询扁平数据
        List<ChildTagItemVo> flatList = templateInfoMapper.selectTemplateStructure(templateName);
        if (flatList == null || flatList.isEmpty()) {
            return new TemplateResponseVo(); // 或抛异常
        }

        // 2. 提取模板id、模板名（所有行相同）
        Long templateId = flatList.get(0).getTemplateId();
        String name = flatList.get(0).getTemplateName();

        // 3. 按 parentTagName 分组（注意：parentTagName 可能为 null）
        Map<String, List<ChildTagItemVo>> grouped = flatList.stream()
                .collect(Collectors.groupingBy(vo ->
                        vo.getParentTagName() == null ? "ROOT" : vo.getParentTagName()
                ));

        // 4. 转换为 ParentTagGroupVo 列表
        List<ParentTagGroupVo> groups = new ArrayList<>();
        for (Map.Entry<String, List<ChildTagItemVo>> entry : grouped.entrySet()) {
            ParentTagGroupVo group = new ParentTagGroupVo();
            group.setParentId(templateTagMapper.selectParentId(entry.getKey()));
            String parentName = "ROOT".equals(entry.getKey()) ? null : entry.getKey();
            group.setParentTagName(parentName);

            List<ChildTagItemVo> children = entry.getValue().stream()
                    .map(this::convertToChildVo)
                    .collect(Collectors.toList());
            group.setChildren(children);

            groups.add(group);
        }

        // 5. 构建响应
        TemplateResponseVo response = new TemplateResponseVo();
        response.setTemplateId(templateId);
        response.setTemplateName(name);
        response.setGroups(groups);
        return response;
    }

    private ChildTagItemVo convertToChildVo(ChildTagItemVo flat) {
        ChildTagItemVo child = new ChildTagItemVo();
        child.setTemplateId(flat.getTemplateId());
        child.setTemplateName(flat.getTemplateName());
        child.setParentTagName(flat.getParentTagName());
        child.setChildTagId(flat.getChildTagId());
        child.setTagName(flat.getTagName());
        child.setTagType(flat.getTagType()); // 前端根据此字段决定控件类型
        // values 初始化为空列表（用户数据另查）
        child.setValue(flat.getValue());
        child.setIsVisible(flat.getIsVisible());
        child.setIsRequired(flat.getIsRequired());
        child.setIsEdit(flat.getIsEdit());
        return child;
    }
}
